package main

import (
	"encoding/json"
	"fmt"
	"io"
	"os"
	"reflect"
	"time"

	"github.com/gin-gonic/gin"
)

type person struct {
	Name string `json:"name"`
	ID   int    `json:"id"`
	Data map[string]interface{}
}

// 中间件
func MiddleWare() gin.HandlerFunc {
	return func(c *gin.Context) {
		t := time.Now()
		fmt.Println("中间件开始执行了....")
		c.Set("request", "中间件")
		// Cookie校验
		_, err := c.Cookie("sessionId")
		if err != nil {
			c.JSON(400, gin.H{"msg": "请登录"})
			c.Abort()
		}
		c.Next()
		status := c.Writer.Status()
		fmt.Println("中间件执行完毕", status)
		t2 := time.Since(t)
		fmt.Println("time:", t2)
	}
}

func main() {
	// 创建路由
	r := gin.Default()
	// 局部中间使用
	r.GET("/", MiddleWare(), func(c *gin.Context) {
		req, _ := c.Get("request")
		cookie, _ := c.Cookie("sessionId")
		fmt.Println("request", req)
		c.JSON(200, gin.H{"request": req, "cookie": cookie})
	})
	// cookie 的set
	r.GET("/cookie", func(c *gin.Context) {
		_, err := c.Cookie("sessionId")
		if err != nil {
			// 第一个参数是key 第二个是value 第三个是超时时间,第四个是存储位置，第五个是作用域，第六个是仅支持https访问
			// 最后一个是是否支持js获取
			c.SetCookie("sessionId", "test", 10, "/", "localhost", false, true)
		}
	})
	// 解析json文件
	r.GET("/json", func(c *gin.Context) {
		// var str map[string]interface{}
		// viper.SetConfigFile("./json/123.json")
		// if err := viper.ReadInConfig(); err != nil {
		// 	if _, ok := err.(viper.ConfigFileNotFoundError); ok {
		// 		// 配置文件未找到错误；如果需要可以忽略
		// 		c.JSON(200, gin.H{"json": "未找到"})
		// 	} else {
		// 		// 配置文件被找到，但产生了另外的错误
		// 		c.JSON(200, gin.H{"json": "解析是失败"})
		// 	}
		// }
		var p person

		file, _ := os.OpenFile("./json/123.json", os.O_RDWR, 0777)
		defer file.Close()
		var buf []byte
		for {
			read := make([]byte, 1024)
			n, err := file.Read(read)
			if err == io.EOF {
				buf = append(buf, read[:n]...)
				break
			}
			buf = append(buf, read[:n]...)

		}
		json.Unmarshal(buf, &p.Data)
		// var p person
		p.Name = "lisi"
		p.ID = 10
		// err := json.Unmarshal(p.Data)
		// if err != nil {
		// 	log.Fatalf("unable to decode into struct, %v", err)
		// }
		p.change(p.Data)
		c.JSON(200, gin.H{"json": p.Data})

		// 处理interface

	})
	r.Run()
}

// 首字母转换
func Capitalize(str string) string {
	var upperStr string
	vv := []rune(str) // 后文有介绍
	for i := 0; i < len(vv); i++ {
		if i == 0 {
			if vv[i] >= 97 && vv[i] <= 122 { // 后文有介绍
				vv[i] -= 32 // string的码表相差32位
				upperStr += string(vv[i])
			} else {
				fmt.Println("Not begins with lowercase letter,")
				return str
			}
		} else {
			upperStr += string(vv[i])
		}
	}
	return upperStr
}

// 判断值类型
func reflectValue(x interface{}, name string) interface{} {
	v := reflect.ValueOf(x)
	k := v.FieldByName(name)
	switch k.Kind() {
	case reflect.Int:
		return k.Int()
	case reflect.String:
		return k.String()
	case reflect.Float64:
		return k.Float()
	default:
		return nil
	}
}

func NameCheck(key string) string {
	switch {
	// 处理解析结构体属性 返回必须是结构体属性
	case key == "Id":
		return "ID"
	default:
		return key
	}
}

func (p *person) getValue(x string, v interface{}) interface{} {
	t := reflect.TypeOf(*p)

	filename := NameCheck(Capitalize(x))
	NameField, _ := t.FieldByName(filename)
	name := NameField.Tag.Get("json")
	switch v.(type) {
	case string:
		if x == name {
			return reflectValue(*p, filename)
		}
	case int:
		if x == name {
			return reflectValue(*p, filename)
		}
	case float64:
		if x == name {
			return reflectValue(*p, filename)
		}
	case []interface{}:
		for _, v2 := range v.([]interface{}) {
			p.getValue(x, v2)
		}
	case map[string]interface{}:
		for k3, v3 := range v.(map[string]interface{}) {
			v.(map[string]interface{})[k3] = p.getValue(k3, v3)
		}
	default:
		return v
	}
	return v
}

// 递归
func (p *person) change(data map[string]interface{}) {
	for k, v := range data {
		data[k] = p.getValue(k, v)
	}
}
